#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>
#include <fcntl.h>

void print_info(char *name,struct stat *attr, bool list)
{
    char perm[]= "rwxrwxrwx";
    if(list)
    {
        for(int i = 0; i < 9; i++) {
            if (attr->st_mode & (1 << (8 - i))) {
                putchar(perm[i]);
            } else {
                putchar('-');
            }
        }
        printf(" %s\n", name);
    }
    else
    {
        printf("%s\n", name);
    }
}

void list_dir(char *path, bool list)
{
    struct stat attr;
    if(stat(path, &attr)== -1) {
        perror("stat error");
        return;
    }
    if (S_ISREG(attr.st_mode)) {
        print_info(path, &attr, list);
        return;
    }
    if (!S_ISDIR(attr.st_mode)) {
        perror("Not a directory");
        return;
    }
    DIR *dir = opendir(path);
    struct dirent *entry;
    while (entry = readdir(dir)) {
        if (entry->d_name[0] == '.')
            continue;
        char full_path[1024];
        snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
        if (stat(full_path, &attr) == -1) {
            perror("stat error");
            continue;
        }
        print_info(entry->d_name, &attr, list);
    }
    closedir(dir);
}

int main(int argc, char *argv[])
{
    int opt;
    bool list=false;
    while((opt=getopt(argc, argv, "l")) != -1) {
        switch(opt) {
            case 'l':
            {
                list = true;
                break;
            }
            default:
            {
                fprintf(stderr, "Usage: %s [-l] <path>\n", argv[0]);
                exit(EXIT_FAILURE);
            }
        }
    }
    if (optind == argc) {
        list_dir(".", list);
    }
    for(int i = optind; i < argc; i++) {
        list_dir(argv[i], list);
    }
    return 0;
}
